/*
 *  NFCSigning - Open source library for signing/validation of NDEF messages
 *  Copyright (C) 2009-2010 The NFCSigning Team
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; either
 *  version 2.1 of the License, or (at your option) any later version.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 *
 */
package parsemeasureverificationtimelog;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author emarkki
 */
public class Main {

    /**
     * 
     * @param iteration
     * @return All Data in iteration
     */
    private static ArrayList<Data> findInIteration(int iteration, ArrayList<Data> datas) {
        ArrayList<Data> res = new ArrayList<Data>();
        for(int i = 0; i < datas.size(); i++) {
            if(datas.get(i).iteration == iteration) {
                res.add(datas.get(i));
            }
        }
        return res;
    }

    /**
     * 
     * @param test
     * @param datas
     * @return The two Data with test
     */
    private static ArrayList<Data> findTestData(int test, ArrayList<Data> datas) {
        ArrayList<Data> res = new ArrayList<Data>();
        for(int i = 0; i < datas.size(); i++) {
            if(datas.get(i).test == test) {
                res.add(datas.get(i));
            }
        }
        return res;
    }

    static class Data {
        int iteration;
        int test;
        int time;
        boolean satsa;
        boolean ok;
        Integer numBytes;

        @Override
        public String toString() {
            return "Data[" + iteration + "," + test + "," + time + "," + satsa + "," + ok + "," + numBytes + "]";
        }


    };
    
    static class FinalRow {
        int iteration;
        Data[] values;

        private FinalRow(int iteration, Data[] values) {
            this.iteration = iteration;
            this.values = values;
        }
    }
    
    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        
        if(args.length < 1) {
            System.err.println("USAGE: java -jar ParseMeasureVerificationTimeLog.jar <log-file> [split-regex]");
            return;
        }
        
        File logFile = new File(args[0]);
        if(!logFile.exists()) {
            System.err.println("No such log file: " + logFile.getAbsolutePath());
            return;
        }
        
        System.out.println("Log-file: " + logFile.getAbsolutePath());

        boolean withSatsa = true;
        if(args.length > 1) {
            withSatsa = Boolean.valueOf(args[1]);
        }
        System.out.println("With SATSA: " + withSatsa);

        String splitRegex = "\\s+";

        if(args.length > 2) {
            splitRegex = args[2];
        }
        System.out.println("Split-regex: " + splitRegex);



        ArrayList<Data> datas = new ArrayList<Data>();
        int maxTest = 0;
        int maxIteration = 0;
        
        BufferedReader in = null;
        
        try {
            in = new BufferedReader(new FileReader(logFile));
            
            String line;
            while((line = in.readLine()) != null) {
                String[] cols = line.split(splitRegex);
                
                if(!"--Result:".equals(cols[0])) {
                    //System.out.println("Skip: \"" + line + "\"");
                    continue;
                }
                
                Data data = new Data();
                
                data.iteration = Integer.parseInt(cols[1]);
                data.test = Integer.parseInt(cols[2]);
                data.time = Integer.parseInt(cols[3]);
                data.satsa = Boolean.parseBoolean(cols[4]);
                if(cols.length >= 6) {
                    data.ok = "OK".equals(cols[5]);
                }
                if(cols.length >= 7) {
                    data.numBytes = Integer.parseInt(cols[6]);
                }
                
                datas.add(data);
                
//                System.out.println("Read: \"" + line + "\"");
                
                maxTest = Math.max(maxTest, data.test);
                maxIteration = Math.max(maxIteration, data.iteration);
//                tests.add(data.test);
            }
            
        } catch (FileNotFoundException ex) {
            Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
        } finally {
            if(in != null) {
                try {
                    in.close();
                } catch (IOException ex) {
                    Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        }
        
        System.out.println("maxTest: " + maxTest);
        
        ArrayList<FinalRow> rows = new ArrayList<FinalRow>();
        
        if(withSatsa) {

            for(int iteration = 0; iteration <= maxIteration; iteration++) {
                Data[] values = new Data[2*(maxTest+1)+1];
                ArrayList<Data> iterationData = findInIteration(iteration, datas);

                for(int test = 0; test <= maxTest; test++) {
                    ArrayList<Data> testData = findTestData(test, iterationData);

                    if(testData.size() == 0) {
                        continue;
                    }

                    if(testData.size() != 2) {
                        System.out.println("Iteration: "+iteration);
                        System.out.println("Test: "+test);
                        //throw new RuntimeException("testData.size() != 2");
                        break;
                    }

    //                System.out.println("testData.size: " + testData.size());

                    Data d1 = testData.get(0);
                    Data d2 = testData.get(1);

                    if(d1.satsa) {
                        Data tmp = d1;
                        d1 = d2;
                        d2 = tmp;
                    }

                    values[2*test+0] = d1;
                    values[2*test+1] = d2;
                }

                rows.add(new FinalRow(iteration, values));
            }
        } else {
            for(int iteration = 0; iteration <= maxIteration; iteration++) {
                Data[] values = new Data[2*(maxTest+1)+1];
                ArrayList<Data> iterationData = findInIteration(iteration, datas);

                for(int test = 0; test <= maxTest; test++) {
                    ArrayList<Data> testData = findTestData(test, iterationData);

                    if(testData.size() == 0) {
                        continue;
                    }

                    if(testData.size() != 1) {
                        System.out.println("Iteration: "+iteration);
                        System.out.println("Test: "+test);
                        //throw new RuntimeException("testData.size() != 2");
                        break;
                    }

    //                System.out.println("testData.size: " + testData.size());

                    Data d1 = testData.get(0);
                    
                    values[test+0] = d1;
                }

                rows.add(new FinalRow(iteration, values));

            }
        }
        
        
        
        /// Output
        
//        System.out.print("\t");
//        
//        for(int i = 0; i < values.length; i++) {
//            
//            System.out.print("t" + i +"\t");
//            System.out.print("n"+"\t");
//            
//            System.out.print("ts" + i + "\t");
//            System.out.print("n"+"\t");
//        }
//        System.out.println();
        
        String sep = ";";

        for(int i = 0; i < rows.size(); i++) {
            FinalRow row = (FinalRow) rows.get(i);
            System.out.print(row.iteration+sep);
            for(int j = 0; j < row.values.length; j++) {
                if(row.values[j] != null) {
                    System.out.print(row.values[j].time+sep);
                    if(row.values[j].numBytes != null) {
                        System.out.print(row.values[j].numBytes);
                    } else {
                        System.out.print("");
                    }
                } else {
                    System.out.print(sep);
                }
                System.out.print(sep);
            }
            System.out.println();
        }
        
        
        
        
    }

}
